// Learn cc.Class:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/class.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/class.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/life-cycle-callbacks.html
// const protobuf = require('protobufjs');

var msg = "message SCDESTORY {" +
    "  optional int32 by = 1 [default = -1];" +
    "  repeated bool answer = 2;" +
    "  optional int32 time = 3;" +
    "  optional int32 from = 4;" +
    "  optional bool result = 5;" +
    "}" +


    "message CSDESTORY {" +
    "  optional bool agree = 1;" +
    "}" +


    "message SCENTERTABLE { " +
    "  required int32 id = 1;" +
    "  required int32 dbid = 2;" +
    "  required string name = 3;" +
    "  required int32 gold = 4;" +
    "  optional string head = 5;" +
    "  required int32 playOrd = 6;" +
    "  optional string ip = 7;" +
    "  optional bool offline = 8;" +
    "  optional bool ready = 9;" +
    "  optional int32 sex = 10;" +
    "  optional int32 point = 11;" +
    "}" +

    " " +
    "message SCLEAVETABLE {" +
    "  required int32 id = 1; " +
    "}" +


    "message BACKGAME {" +
    "  required int32 id = 1;  " +
    "  required int32 tid = 2;   " +
    "  optional string ticket = 3;" +
    "}" +

    "message SCGOLDCHANGE {" +
    "  required int32 type = 1;  " +
    "  required int32 gold = 2;   " +
    "}" +



    "message SCGAMECHAT {" +
    "  required int32 from = 1;" +
    "  required int32 type = 2;" +
    "  required string info = 3;" +
    "}" +

    "message CSGAMECHAT {" +
    "  required int32 type = 1;" +
    "  required string info = 2;" +
    "}" +

    "message PLAYERSTART {" +
    "   required int32 id = 1;  " +
    "}" +

    "message USEROFFLINE {" +
    "   required int32 id = 1;  " +
    "   required bool state = 2;" +
    "}" +

    "message SCMESSAGE {" +
    "   optional int32 type = 1;  " +
    "   optional string msg = 2;" +
    "}" +


    "message SCQUICK {" +
    "   required int32 id = 1;  " +
    "   required bool agree = 2;" +
    "}" +


    "message SCQUICKEX {" +
    "   required int32 id = 1;  " +
    "   required int32 agree = 2;" +
    "}" +

    "message SCTURN{" +
    "  required int32 id = 1;" +
    "}" +

    "message CSQUICK {" +
    "   required bool agree = 1;" +
    "}" +


    "message CSQUICKEX {" +
    "    required int32 agree = 1;" +
    "  }" +


    "message SCGIVEUP {" +
    "  optional int32 id = 1;" +
    "  optional int32 time = 2;" +
    "}" +

    "message CSGIVEUP {" +
    "   required bool agree = 1;" +
    "}" +


    "message SCSAY {" +
    "  required int32 from = 1;" +
    "  optional int32 to = 2; " +
    "  required int32 type = 3;" +
    "  required string info = 4;" +
    "}" +

    "message CSSAY {" +
    "  optional int32 to = 1;" +
    "  required int32 type = 2;" +
    "  required string info = 3;" +
    "}" +

    "message SCLOCAL {" +
    "  optional int32 id = 1 [default = -1];" +
    "  optional string local = 2;" +
    "}" +

    "message CSLOCAL {" +
    "  optional string local = 1;" +
    "} " +

    "message SCAUTOOUTCARD {" +
    "  required int32 type = 1; " +
    "}" +

    "message CSAUTOOUTCARD {" +

    "} " +


    "message recordplayer{" +
    "  required int32 dbid = 1;" +
    "  optional int32 id = 2;" +
    "  required string name = 3;" +
    "  required int32 point = 4;" +
    "  required int32 gold = 5;" +
    "  required int32 playOrd = 6;" +
    "  optional int32 sex = 7 [default = 1];" +
    "}" +


    "message packet {" +
    "  required string id = 1;" +
    "  required bytes data = 2;" +
    "}" +


    "message vote{" +
    "    optional int32 by = 1 [default = -1];" +
    "    repeated bool answer = 2;" +
    "    optional int32 time = 3; " +
    "}" +


    "message SCDISMISS{" +
    "   optional int32 type = 1 [default = 0];" +
    "}" +


    "message ERROR {" +
    "  optional string msg = 1;" +
    "  optional int32 code = 2;" +
    "}" +

    "message CREATEAGENCY{" +
    "  optional int32 type = 1 [default = -1];" +
    "  optional int32 turn = 2;" +
    "  optional string ticket = 3;" +
    "}" +

    "message JOINMATCH {" +
    "  optional int32 matchid = 1;" +
    "  optional int32 masterid = 2;" +
    "  optional string ticket = 3;" +
    "}" +


    "message JOINMATCHROOM {" +
    "   optional int32 matchid = 1;" +
    "   optional int32 masterid = 2;" +
    "   optional int32 roomid = 3;" +
    "   optional string ticket = 4;" +
    "}" +


    "message NEWMATCH {" +
    "   optional int32 matchid = 1;" +
    "   optional int32 masterid = 2;" +
    "   optional string ticket = 3;" +
    "}" +

    "message CSJSONROOM {" +
    "  optional int32 id = 1;" +
    "  optional int32 tid = 2; " +
    "}" +


    "message TABLEINFO {" +
    "  required int32 tid = 1;" +
    "  optional int32 matchid = 2; " +
    "  optional bool state = 3 [default = false]; " +
    "  repeated int32 player =4; " +
    "}" +


    "message TABLELIST {" +
    "  repeated TABLEINFO tables = 1;" +
    "}" +

    "message HEADINFO {" +
    "  required int32 id = 1;" +
    "  required string url = 2; " +
    "}" +

    "message SCHEADMAP {" +
    "  repeated HEADINFO heads = 1;" +
    "}" +

    "message CSGETHEAD {" +
    "  repeated int32 id = 1;" +
    "}" +

    "message CSLOGIN {" +
    "  required int32 id = 1;" +
    "  optional string url = 2;" +
    "}" +

    "message CSGETTABLES {" +
    "  repeated int32 matchid = 1;" +
    "}";

module.exports = {
    mIsInit: false,
    root: null,
    mEnCodeBuf: null,
    mGameMsg: [],
    init(gameMsg) {
        this.mIsInit = true;
        if (this.mEnCodeBuf == null)
            this.mEnCodeBuf = new Uint8Array(1000);
        if (gameMsg === undefined) {
            if (this.root !== undefined)
                return;
            gameMsg = '';
        }
        this.root = protobuf.parse(msg + gameMsg).root;
    },

    base64ByteLength(str) {
        // Handle padding
        var bytes = str.length;
        if (str.charCodeAt(bytes - 1) === 0x3D)
            bytes--;
        if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D)
            bytes--;
        return (bytes * 3) >>> 2;
    },

    encode(name, message) {
        if (!this.mIsInit) {
            this.init();
        }
        var obj = this.root.lookup(name);
        if (obj) {
            try {
                return obj.encode(message).finish();

            } catch (error) {
                cc.log(error);
                return null;
            }
        }
        cc.log(name + ' encode protobuf error');
        return null;
    },

    encodeDelimited(name, message) {
        if (!this.mIsInit) {
            this.init();
        }
        var obj = this.root.lookup(name);
        if (obj) {
            try {
                return obj.encodeDelimited(message).finish();

            } catch (error) {
                cc.log(error);
                return null;
            }
        }
        cc.log(name + ' encode protobuf error');
        return null;
    },

    decode(name, buffer) {
        if (!this.mIsInit) {
            this.init();
        }
        var obj = this.root.lookup(name);
        if (obj) {
            try {
                return obj.decode(buffer);

            } catch (error) {
                cc.log(error);
                return null;
            }
        }
        cc.log(name + ' decode protobuf error');
        return null;
    },

    decodeDelimited(name, buffer) {
        if (!this.mIsInit) {
            this.init();
        }
        var obj = this.root.lookup(name);
        if (obj) {
            try {
                return obj.decodeDelimited(buffer);

            } catch (error) {
                cc.log(error);
                return null;
            }
        }
        cc.log(name + ' decode protobuf error');
        return null;
    },

    encodeToSocket(name, message) {
        var val = this.encode(name, message);
        if (val) {
            return protobuf.util.base64.encode(val, 0, val.length);
            //     return JSON.stringify(Array.from(val));
        }

    },

    decodeGameInfo(item) {
        var info = this.decodeRecord(item);
        var obj = this.root.lookup(info.id);
        return obj.decode(info.data);

    },

    decodePacket(item) {
        var info = this.decodeRecord(item);
        var obj = this.root.lookup(info.id);
        return {
            id: info.id,
            msg: obj.decode(info.data)
        };
    },

    decodeRecord(dataStr) {
        var obj = this.root.lookup('packet');
        protobuf.util.base64.decode(dataStr, this.mEnCodeBuf, 0);
        return obj.decode(this.mEnCodeBuf, this.base64ByteLength(dataStr));

    },

    decodeFromReocrdStr(str) {
        if (!this.mIsInit) {
            this.init();
        }
        var strlst = str.split('|');
        //先数据
        var dataList = [];
        dataList.push(this.decodeGameInfo(strlst[0]));

        for (var i = 1; i < strlst.length; i++) {
            dataList.push(this.decodePacket(strlst[i]));
        }
        return dataList;
    },

    decodeFromSocket(name, msg) {
        if (!this.mIsInit) {
            this.init();
        }
        var obj = this.root.lookup(name);
        if (msg == null || msg == '')
            return '';
        if (obj) {
            try {
                if (msg.indexOf('"') != -1) {
                    msg = msg.substr(1, msg.length - 2);
                }

                protobuf.util.base64.decode(msg, this.mEnCodeBuf, 0)
                //  cc.log(' decodeFromSocket  333 ');
                return obj.decode(this.mEnCodeBuf, this.base64ByteLength(msg));
            } catch (error) {
                cc.log(' decodeFromSocket name :' + name + ' error:' + error + '');
                return error;
            }
        }
        return new Error('name :' + name + ' decodeFromSocket protobuf error');
    }
};

// module.exports = PBManager;